package org.bd.survey.template;

import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.CommonsClientHttpRequestFactory;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
import org.springframework.social.facebook.FacebookLink;
import org.springframework.social.facebook.FacebookOperations;
import org.springframework.social.facebook.FacebookProfile;
import org.springframework.social.facebook.FacebookTemplate;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestOperations;
import org.springframework.web.client.RestTemplate;
import sun.net.www.http.HttpClient;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * User: naim
 * Date: Nov 21, 2010
 */
public class ModifiedFacebookTemplate implements FacebookOperations {
	RestOperations restOperations;
	private final String accessToken;

	public ModifiedFacebookTemplate(String accessToken) {
		this.accessToken = accessToken;
		RestTemplate restTemplate = new RestTemplate();

        org.apache.commons.httpclient.HttpClient httpClient =  new org.apache.commons.httpclient.HttpClient(new SimpleHttpConnectionManager(true));
		restTemplate.setRequestFactory(new CommonsClientHttpRequestFactory(httpClient));
		MappingJacksonHttpMessageConverter json = new MappingJacksonHttpMessageConverter();
		json.setSupportedMediaTypes(Arrays.asList(new MediaType("text", "javascript")));
		restTemplate.getMessageConverters().add(json);
		this.restOperations = restTemplate;
	}

	public String getProfileId() {
		return Long.toString(getUserProfile().getId());
	}

	public String getProfileUrl() {
		return "http://www.facebook.com/profile.php?id=" + getProfileId();
	}

	public FacebookProfile getUserProfile() {
		return restOperations.getForObject(OBJECT_URL + "?access_token={accessToken}", FacebookProfile.class, "me",
				accessToken);
    }

	public List<String> getFriendIds() {
		@SuppressWarnings("rawtypes")
        ResponseEntity<Map> response = restOperations.getForEntity(CONNECTION_URL, Map.class, CURRENT_USER, FRIENDS,
				accessToken);

		@SuppressWarnings("unchecked")
		Map<String, List<Map<String, String>>> resultsMap = response.getBody();
		List<Map<String, String>> friends = resultsMap.get("data");

		List<String> friendIds = new ArrayList<String>();
		for (Map<String, String> friendData : friends) {
	        friendIds.add(friendData.get("id"));
        }
	    return friendIds;
    }

	public void updateStatus(String message) {
		MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
		map.set("message", message);
		publish(CURRENT_USER, FEED, map);
	}

	public void updateStatus(String message, FacebookLink link) {
		MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
		map.set("link", link.getLink());
		map.set("name", link.getName());
		map.set("caption", link.getCaption());
		map.set("description", link.getDescription());
		map.set("message", message);
		publish(CURRENT_USER, FEED, map);
	}

	public void publish(String object, String connection, MultiValueMap<String, String> data) {
		MultiValueMap<String, String> requestData = new LinkedMultiValueMap<String, String>(data);
		restOperations.postForLocation(CONNECTION_URL, requestData, object, connection, accessToken);
	}

	public byte[] getProfilePicture() {
		return getProfilePicture(CURRENT_USER);
	}

	public byte[] getProfilePicture(String profileId) {
		ResponseEntity<byte[]> imageBytes = restOperations.getForEntity(PROFILE_LARGE_PICTURE_URL, byte[].class,
				profileId, accessToken);
		return imageBytes.getBody();
	}

	static final String PROFILE_LARGE_PICTURE_URL = "https://graph.facebook.com/{profile}/picture?type=large&access_token={accessToken}";
	static final String OBJECT_URL = "https://graph.facebook.com/{objectId}";
	static final String CONNECTION_URL = OBJECT_URL + "/{connection}?access_token={accessToken}";

	static final String FRIENDS = "friends";
	static final String FEED = "feed";
	static final String CURRENT_USER = "me";
}
